<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// $Id: CacheFile.class.php 2791 2012-02-29 10:08:57Z liu21st $

/**
 +------------------------------------------------------------------------------
 * 文件类型缓存类
 +------------------------------------------------------------------------------
 * @category   Think
 * @package  Think
 * @subpackage  Util
 * @author    liu21st <liu21st@gmail.com>
 * @version   $Id: CacheFile.class.php 2791 2012-02-29 10:08:57Z liu21st $
 * @last modify 2012-12-12 17:22:20 by mashanling
 +------------------------------------------------------------------------------
 */
class CacheFile extends Cache {
    protected $prefix='~@';//缓存存储前缀;

    /**
     * 取得变量的存储文件名
     *
     * @last modify 2012-12-12 17:32:53 by mashanling
     *
     * @access private
     *
     * @param string $name 缓存变量名
     *
     * @return string 变量文件路径
     */
    private function filename($name) {
        $name	=	md5($name);

        if(C('DATA_CACHE_SUBDIR')) {//使用子目录
            $dir = '';
            $len = C('DATA_PATH_LEVEL');

            for($i = 0; $i < $len; $i++) {
                $dir	.=	$name{$i} . '/';
            }

            !is_dir($v = $this->options['temp'] . $dir) && mk_dir($v, 0755, true);

            $filename	=	$dir . $this->prefix . $name . '.php';
        }
        else{
            $filename	=	$this->prefix . $name.'.php';
        }

        return $this->options['temp'] . $filename;
    }

    /**
     * 构造函数
     *
     * @last modify 2012-12-12 17:22:34 by mashanling
     *
     * @access public
     *
     * @return void 无返回值
     */
    public function __construct($options = '') {
        $this->options = $options ? $options : $this->options;
        $this->options['temp'] = empty($options['temp']) ? C('DATA_CACHE_PATH') : $options['temp'];
        $this->options['temp'] .= '/' == $this->options['temp'] ? '' : '/';

        !is_dir($v = $this->options['temp']) && mkdir($v, 0755, true);

        $this->options['expire'] = isset($options['expire']) ? $options['expire'] : C('DATA_CACHE_TIME');
        $this->options['length'] = isset($options['length']) ? $options['length'] : 0;
        $this->connected = true;
    }

    /**
     * 清除缓存
     *
     * @last modify 2012-12-12 17:47:44 by mashanling
     *
     * @access public
     *
     * @param string $name 缓存变量名
     *
     * @return void 无返回值
     */
    public function clear() {
        $path = $this->options['temp'];

        if ($dir = opendir($path)) {
            while (false !== ($file = readdir($dir))) {
                !is_dir($file) && unlink( $path . $file );
            }

            closedir( $dir );
        }
    }

    /**
     * 读取缓存
     *
     * @last modify 2012-12-12 17:38:11 by mashanling
     *
     * @access public
     *
     * @param string $name 缓存变量名
     *
     * @return mixed 缓存内容
     */
    public function get($name) {
        $filename = $this->filename($name);

        if (!is_file($filename)) {
           return false;
        }

        N('cache_read', 1);

        $content = file_get_contents($filename);

        if( false !== $content) {
            $expire = intval(substr($content, 8, 12));

            if($expire && time() > filemtime($filename) + $expire) {//缓存过期删除缓存文件
                unlink($filename);
                return false;
            }

            if(C('DATA_CACHE_CHECK')) {//开启数据校验
                $check   = substr($content, 20, 32);
                $content = substr($content, 52, -3);

                if($check != md5($content)) {//校验错误
                    return false;
                }
            }
            else {
                $content = substr($content, 20, -3);
            }

            if(C('DATA_CACHE_COMPRESS') && GZCOMPRESS) {//启用数据压缩
                $content = gzuncompress($content);
            }

            return unserialize($content);
        }
        else {
            return false;
        }
    }//end get

    /**
     * 删除缓存
     *
     * @last modify 2012-12-12 17:46:57 by mashanling
     *
     * @access public
     *
     * @param string $name 缓存变量名
     *
     * @return bool 删除成功，返回true，否则返回false
     */
    public function rm($name) {
        return unlink($this->filename($name));
    }

    /**
     * 写入缓存
     *
     * @last modify 2012-12-12 17:42:46 by mashanling
     *
     * @access public
     *
     * @param string $name  缓存变量名
     * @param mixed $value  存储数据
     * @param int   $expire 有效时间 0为永久
     *
     * @return bool 写入成功，返回true，否则返回false
     */
    public function set($name, $value, $expire = null) {
        N('cache_write', 1);
        $expire   = null === $expire ? $this->options['expire'] : $expire;
        $filename = $this->filename($name);
        $data     =   serialize($value);

        if( C('DATA_CACHE_COMPRESS') && GZCOMPRESS) {//数据压缩
            $data = gzcompress($data,3);
        }

        $check  = C('DATA_CACHE_CHECK') ? md5($data) : '';//开启数据校验检测
        $data   = "<?php\n//" . sprintf('%012d', $expire) . $check . $data . "\n?>";
        $result = file_put_contents($filename, $data);

        if($result) {

            if($this->options['length']) {//记录缓存队列
                $this->queue($name);
            }

            clearstatcache();
            return true;
        }
        else {
            return false;
        }
    }//end set
}